use std::{rc::Rc, cell::RefCell};

use super::{ClassReader, ConstantPool, attribute_info::{self, attr_code::CodeAttribute, attr_constant_value::ConstantValueAttribute}, Attribute, ExceptionsAttribute};


// field_info {
// u2             access_flags; // 访问标志（private public protected）
// u2             name_index;  // 名称常量池索引
// u2             descriptor_index; // 描述符常量池索引
// u2             attributes_count; // 属性个数
// attribute_info attributes[attributes_count]; // 属性表集合
// }
// method_info {
// u2             access_flags;
// u2             name_index;
// u2             descriptor_index;
// u2             attributes_count;
// attribute_info attributes[attributes_count];
// }
pub struct MemberInfo {
    cp: Rc<RefCell<ConstantPool>>,
    accsess_flags: u16,
    name_index: u16,
    descriptor_index: u16,
    attributes: Vec<Attribute>,
}

impl MemberInfo {
    
    // 读取字段表或方法表
    pub fn read_members(reader: &mut ClassReader, cp: Rc<RefCell<ConstantPool>>) -> Vec<MemberInfo> {
        let count = reader.read_u16();
        (0..count).map(|_| Self::read_member(reader, cp.clone())).collect()
    }

    // 读取字段或方法数据
    pub fn read_member(reader: &mut ClassReader, cp: Rc<RefCell<ConstantPool>>) -> MemberInfo {
        MemberInfo { 
            cp: cp.clone(),
            accsess_flags: reader.read_u16(), 
            name_index: reader.read_u16(), 
            descriptor_index: reader.read_u16(),
            attributes: attribute_info::read_attributes(reader, cp)
        }
    }

    pub fn access_flags(&self) -> u16 {
        self.accsess_flags
    }

    // 常量池查找名称
    pub fn name(&self) -> String {
        self.cp.borrow().get_utf8(self.name_index as usize)
    }

    // 常量池查找描述符
    pub fn descriptor(&self) -> String{
        self.cp.borrow().get_utf8(self.descriptor_index as usize)
    }

    // 获取code_attribute
    pub fn code_attribute(&self) -> Option<&CodeAttribute> {
        for attr in &self.attributes {
            if let Attribute::CodeAttribute(code) = attr {
                return Some(code);
            }
        }
        None
    }

    // 获取ConstantValueAttribute
    pub fn constant_value_attribute(&self) -> Option<&ConstantValueAttribute> {
        for attr in &self.attributes {
            if let Attribute::ConstantValueAttribute(code) = attr {
                return Some(code);
            }
        }
        None
    }

    pub fn exceptions_attribute(&self) -> Option<ExceptionsAttribute> {
        for attribute_info in &self.attributes {
            if let Attribute::ExceptionsAttribute(attr) = attribute_info {
                return Some(attr.clone());
            }
        }
        None
    }

    pub fn runtime_visible_annotations_attribute_data(&self) -> Vec<u8> {
        self.get_unparsed_attribute_data("RuntimeVisibleAnnotations")
    }

    pub fn runtime_visible_parameter_annotations_attribute_data(&self) -> Vec<u8> {
        self.get_unparsed_attribute_data("RuntimeVisibleParameterAnnotationsAttribute")
    }

    pub fn annotation_default_attribute_data(&self) -> Vec<u8> {
        self.get_unparsed_attribute_data("AnnotationDefault")
    }

    fn get_unparsed_attribute_data(&self, name: &str) -> Vec<u8> {
        for attr_info in &self.attributes {
            if let Attribute::UnparsedAttribute(unparsed_attr) = attr_info {
                if unparsed_attr.get_name() == name {
                    return unparsed_attr.info();
                }
            }
        }   
        vec![]
    }
}